<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>编程风格</title>
</head>

<body>
    <script>
        /**
    1、块级作用域
    ① let 取代 var 语义完全相同 且 let 没有副作用
    ② 全局常量和线程安全
      在let 和 const 之间 ，建议优先使用const ,尤其是在全局环境，补一年设置变量应该设置常量。

      const 优于let 有几个原因。一个是const 可以提醒阅读程序的人，这个变量不应改改变；另一个是 const 比较符合函数式编程思想，运算不改变值，只新建值，这样也有利于将来的分布式运算，最后一个原因是JavaScript 编译器会对const进行优先化，所以多使用const ,有利于提高程序的运行效率，也就是说let 和 const 本质区别，其实是编译器内部处理不同。

      const 声明常量还是有两个好处，一是于都代码的人立刻会意识到不应改修改这个值 ，二是防止了无意间修改变量值所导致的错误。

      所有的函数都应该设置为常量

      2、字符串
      静态字符串一律使用引号或者反引号 ，不使用双引号，动态字符串使用反引号
    */
        // bad
        // const a = "foobar";
        // const b = 'foo' + a + 'bar';

        // acceptable
        const c = `foobar`;

        // good
        const a = 'foobar';
        const b = `foo${a}bar`;

        // 3、解构赋值  使用数组成员变量赋值时 优先使用解构赋值
        const arr = [1, 2, 3, 4, 5];

        // bad
        // const first = arr[0]
        // const second = arr[1]

        // good 
        const [first, second] = arr

        // 函数的参数如果是对象的成员，优先使用解构赋值
        // bad
        function getFullName(user) {
            const firstName = user.firstName
            const lastName = user.lastName
        }

        // good
        function getFullName2(obj) {
            const {
                firstName,
                lastName
            } = obj;
        }

        // best 
        function getFullName3({
            firstName,
            lastName
        }) {

        }

        // 如果函数返回多个值，优先使用对象的解构赋值，而不是数组的解构赋值，这样便于以后添加返回值，以及更改返回值的顺序

        // bad
        // function processInput(input) {
        //     return [left, right, top, bottom]
        // }
        // good 
        function processInput2(input) {
            return {
                left,
                right,
                top,
                bottom
            }
        }
        // const {
        //     left,
        //     right
        // } = processInput2(input);

        //4、对象 单行定义的对象，最后一个成员不以逗号结尾，多行定义的对象最后用逗号结尾
        // bad
        // const a = {
        //     k1: v1,
        //     k2: v2,
        // };
        // const b = {
        //     k1: v1,
        //     k2: v2
        // };

        // // good
        // const a = {
        //     k1: v1,
        //     k2: v2
        // };
        // const b = {
        //     k1: v1,
        //     k2: v2,
        // };

        // 对象尽量静态化，一旦定义，就不得随意添加新的属性。如果添加属性不可避免，要使用Object.assign 方法。
        // bad
        const a0 = {}
        a0.x = 3;
        // if reshae unavoidable 
        const a1 = {}
        Object.assign(a1, {
            x: 3
        })
        // good 
        const a2 = {
            x: null
        }
        a2.x = 3
        // 如果对象的属性名是动态的，可以在创造对象的时候，使用属性表达式定义。

        // bad
        // const obj = {
        //     id: 5,
        //     name: 'San Francisco',
        // };
        // obj[getKey('enabled')] = true;

        // // good
        // const obj = {
        //     id: 5,
        //     name: 'San Francisco',
        //     [getKey('enabled')]: true,
        // };
        // 对象的属性和方法，尽量采用简洁表达法，这样易于描述和书写。
        var ref = 'some value';

        // bad
        const atom = {
            ref: ref,

            value: 1,

            addValue: function (value) {
                return atom.value + value;
            },
        };

        // good
        const atom = {
            ref,

            value: 1,

            addValue(value) {
                return atom.value + value;
            },
        };

        // 5、使用扩展运算符(...)拷贝数组
        // bad
        const len = items.length;
        const itemsCopy = [];
        let i;

        for (i = 0; i < len; i++) {
            itemsCopy[i] = items[i];
        }

        // good
        const itemsCopy = [...items];

        // 使用 Array.from 方法，将类似数组的对象转为数组。
        // const foo = document.querySelectorAll('.foo');
        // const nodes = Array.from(foo);

        // 6、 函数
        // 立即执行函数可以写成箭头函数的形式
        (() => {
            console.log('Welcome to the Internet.')
        })()
        // 哪些使用匿名函数当做参数的场合 尽量使用箭头函数代替 ，因为这样更简洁,而且绑定了this 
        // bad
        [1, 2, 3].map(function (x) {
            return x * x
        })

        // good 
        [1, 2, 3].map((x) => {
            return x * x
        })
        //best 
        [1, 2, 3].map(x => x * x)
    </script>
</body>

</html>